
#include <QMenuBar>
#include <QMenu>
#include <QFile>
#include <QDateTime>
#include <QFileDialog>
#include <QMessageBox>
#include <QStatusBar>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QDebug>
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    widgetsInit();
    layoutInit();
    logMenuInit("命令日志", commandDisplay);
    logMenuInit("设备日志", deviceLogDisplay);
}

MainWindow::~MainWindow()
{
}

void MainWindow::widgetsInit()
{
    /* central widget */
    centralWidget = new QWidget(this);
    setCentralWidget(centralWidget);
    setWindowTitle("设备管理工具 v1.0");
    setMinimumSize(1200, 800);

    /* framework widget */
    leftWidget = new QWidget(this);
    rightWidget = new QWidget(this);
    settingGroup = new QGroupBox("串口设置", this);
    deviceGroup = new QGroupBox("设备操作", this);
    commandGroup = new QGroupBox("命令日志", this);
    deviceLogGroup = new QGroupBox("设备日志", this);

    /* setting */
    serialPortLabel = new QLabel("串口COM", this);
    serialPortLabel->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
    serialPortComboBox = new QComboBox(this);
    baudRateLabel = new QLabel("波特率", this);
    baudRateLabel->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
    baudRateComboBox = new QComboBox(this);
    refreshSerialPortBtn = new QPushButton("刷新串口", this);
    opSerialPortBtn = new QPushButton("打开串口", this);

    /* firmware management */
    readFirmBtn = new QPushButton("读取固件", this);
    upgradeFirmBtn = new QPushButton("更新固件", this);
    readVersionBtn = new QPushButton("读取版本", this);
    resetBtn  = new QPushButton("复位设备", this);
    progressBar = new QProgressBar(this);
    progressBar->setVisible(true);
    progressBar->setStyleSheet(
        "QProgressBar {"
        "    border: 2px solid grey;"
        "    border-radius: 5px;"
        // "    background-color: #F0F0F0;"
        "    text-align: center;"
        "}"
        "QProgressBar::chunk {"
        "    background-color: #4CAF50;"
        "    border-radius: 3px;"
        "}"
        );
    progressBar->setValue(0);

    /* device management */
    readUUIDBtn = new QPushButton("读取UUID", this);
    setKeyBtn = new QPushButton("设置密钥", this);
    readConfigBtn = new QPushButton("读取配置", this);
    setConfigBtn = new QPushButton("设置配置", this);

    /* command */
    commandInput = new QLineEdit(this);
    commandInput->setPlaceholderText("输入命令...");
    sendCommandBtn = new QPushButton("发送", this);
    commandDisplay = new QTextEdit(this);
    commandDisplay->setReadOnly(true);
    commandDisplay->setLineWrapMode(QTextEdit::NoWrap);
    commandDisplay->setFont(QFont("Consolas", 9));

    /* device log */
    deviceLogDisplay = new QTextEdit(this);
    deviceLogDisplay->setReadOnly(true);
    deviceLogDisplay->setLineWrapMode(QTextEdit::NoWrap);
    deviceLogDisplay->setFont(QFont("Consolas", 9));

}

void MainWindow::layoutInit()
{
    QHBoxLayout *settingLayout = new QHBoxLayout(settingGroup);
    settingLayout->addWidget(serialPortLabel);
    settingLayout->addWidget(serialPortComboBox);
    settingLayout->addWidget(baudRateLabel);
    settingLayout->addWidget(baudRateComboBox);
    settingLayout->addWidget(opSerialPortBtn);
    settingLayout->addWidget(refreshSerialPortBtn);

    QGridLayout *deviceLayout = new QGridLayout(deviceGroup);
    deviceLayout->addWidget(readFirmBtn, 0, 0);
    deviceLayout->addWidget(upgradeFirmBtn, 0, 1);
    deviceLayout->addWidget(readVersionBtn, 0, 2);
    deviceLayout->addWidget(resetBtn, 0, 3);
    deviceLayout->addWidget(readUUIDBtn, 1, 0);
    deviceLayout->addWidget(setKeyBtn, 1, 1);
    deviceLayout->addWidget(readConfigBtn, 1, 2);
    deviceLayout->addWidget(setConfigBtn, 1, 3);
    deviceLayout->addWidget(progressBar, 2, 0, 1, 4);

    QHBoxLayout *commandInputLayout = new QHBoxLayout();
    commandInputLayout->addWidget(commandInput);
    commandInputLayout->addWidget(sendCommandBtn);
    QVBoxLayout *commandLayout = new QVBoxLayout(commandGroup);
    commandLayout->addLayout(commandInputLayout);
    commandLayout->addWidget(commandDisplay);

    QVBoxLayout *deviceLogLayout = new QVBoxLayout(deviceLogGroup);
    deviceLogLayout->addWidget(deviceLogDisplay);

    QVBoxLayout *leftLayout = new QVBoxLayout(leftWidget);
    leftLayout->setContentsMargins(0, 0, 5, 0);
    leftLayout->addWidget(settingGroup);
    leftLayout->addWidget(deviceGroup);
    leftLayout->addWidget(commandGroup);
    // leftLayout->setStretchFactor(settingGroup, 1);
    // leftLayout->setStretchFactor(deviceGroup, 1);
    leftLayout->setStretchFactor(commandGroup, 6); // 命令终端占用更多空间

    QVBoxLayout *rightLayout = new QVBoxLayout(rightWidget);
    rightLayout->setContentsMargins(5, 0, 0, 0); // 左侧留出间距
    rightLayout->addWidget(deviceLogGroup);
    rightLayout->setStretchFactor(deviceLogGroup, 1);

    QHBoxLayout *mainLayout = new QHBoxLayout(centralWidget);
    mainLayout->addWidget(leftWidget, 5);  // 左侧占50%
    mainLayout->addWidget(rightWidget, 5); // 右侧占50%
}

void MainWindow::logMenuInit(const QString &title, QTextEdit* textEdit)
{
    QMenu *logMenu = menuBar()->addMenu(title);
    QAction *saveLogAction = logMenu->addAction("保存日志");
    QAction *clearLogAction = logMenu->addAction("清空日志");
    connect(saveLogAction, &QAction::triggered, this, [this, textEdit](){
        QString fileName = QFileDialog::getSaveFileName(this,
                                                        "保存文件",
                                                        QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss"),
                                                        "日志文件 (*.txt);;所有文件 (*.*)");

        if (!fileName.isEmpty()) {
            QFile file(fileName);
            if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
                QTextStream stream(&file);
                stream << textEdit->toPlainText();
                file.close();
                this->statusBar()->showMessage("文件保存成功", 3000);
            } else {
                QMessageBox::warning(this, "错误", "无法保存文件");
            }
        }
    });
    connect(clearLogAction, &QAction::triggered, this, [textEdit](){
        textEdit->clear();
    });
}

